home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / graphics / mdl10.zoo / unix_xdl.zoo / xdl.c < prev    next >
C/C++ Source or Header  |  1993-06-04  |  16KB  |  572 lines

  1. /*
  2.  * xdl 2.0 -- display a DL animation in an X-window.
  3.  *
  4.  *
  5.  * Author:
  6.  *      Jonas Yngvesson <jonas-y@isy.liu.se>
  7.  *
  8.  * Derived from dltogl.c by:
  9.  *    George Phillips <phillips@cs.ubc.ca>
  10.  *
  11.  * Support for user defined animation speed:
  12.  *      Per Beremark <per.beremark@telelogic.se>
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <signal.h>
  17. #ifdef __convex__
  18. #include <stdlib.h>
  19. #else
  20. #include <malloc.h>
  21. #endif
  22. #include <sys/types.h>
  23. #include <sys/time.h>
  24.  
  25. #include <X11/Xos.h>
  26. #include <X11/Xlib.h>
  27. #include <X11/Xutil.h>
  28.  
  29. #define isneg16(x)    ((x) & 0x8000)
  30. #define neg16(x)    ((~(x) + 1) & 0x7fff)
  31.  
  32.  
  33. typedef struct {
  34.     int   version;
  35.     int   format;
  36.     int   images_per_screen;
  37.     char  title[21];
  38.     char  author[21];
  39.     int   num_screen;
  40.     int   num_command;
  41. } DL_info;
  42.  
  43.  
  44. Display *x_display;
  45. Window   x_window;
  46. int      x_depth;
  47. u_long   pixels[256];
  48. Pixmap  *pixmap;
  49. XImage  *x_image;
  50. GC       gc_clear;
  51.  
  52.  
  53. /*
  54.  * Initialize the colormap. I use a private one for PseudoColor,
  55.  * I was too tired to fiddle with allocating shared colors.
  56.  */
  57. static void
  58. colormap_setup(fp, version)
  59.     FILE *fp;
  60.     int   version;
  61. {
  62.     Colormap cmap;
  63.     XColor   color;
  64.     u_char   pal[768];
  65.     int      i;
  66.  
  67.     /* Is this the border colour? */
  68.     if (version == 2)
  69.         for (i = 0; i < 3; i++)
  70.             fgetc(fp);
  71.     else
  72.         fgetc(fp);
  73.     
  74.     /*
  75.      * Here comes the colormap.
  76.      */
  77.     fread(pal, 1, 768, fp);
  78.     
  79.     /*
  80.      * Set up for grayscale conversion on a monochrome display.
  81.      */
  82.     if (x_depth == 1) {
  83.         for (i = 0; i < 256; i++) {
  84.             pixels[i] = (u_long)((pal[3 * i] << 2) * 0.30 
  85.                                  + (pal[3 * i + 1] << 2) * 0.59
  86.                                  + (pal[3 * i + 2] << 2) * 0.11);
  87.         }
  88.         return;
  89.     }
  90.         
  91.     /*
  92.      * Allocate colors on color displays.
  93.      */
  94.     if (x_depth == 8) {
  95.         cmap = XCreateColormap(x_display, x_window, 
  96.                    DefaultVisual(x_display, 
  97.                          DefaultScreen(x_display)),
  98.                                AllocNone);
  99.     } else {
  100.         cmap = DefaultColormap(x_display, DefaultScreen(x_display));
  101.     }
  102.  
  103.     for (i = 0; i < 256; i++) {
  104.         /*
  105.          * X wants 16 bit color specs and VGA uses 6 ==> shift 10 bits.
  106.          */
  107.         color.red   = pal[3 * i    ] << 10;
  108.         color.green = pal[3 * i + 1] << 10;
  109.         color.blue  = pal[3 * i + 2] << 10;
  110.         XAllocColor(x_display, cmap, &color);
  111.         pixels[i] = color.pixel;
  112.     }
  113.  
  114.     if (x_depth == 8) {        
  115.         XSetWindowColormap(x_display, x_window, cmap);
  116.     }
  117. }
  118.  
  119.  
  120.  
  121. /*
  122.  * Wait for a key to be pressed. In "dltogl" it was
  123.  * printed as a "waitkey" command to GL with a numeric
  124.  * argument. I don't know any GL commands so I don't know
  125.  * if the argument was a request to wait for a specific key
  126.  * or a timeout for how long to wait or anything else.
  127.  * I just wait forever for any key to be pressed.
  128.  */
  129. static void
  130. wait_for_key()
  131. {
  132.     XEvent event;
  133.     Bool   done;
  134.  
  135.     done = False;
  136.     while (!done) {
  137.         XNextEvent(x_display, &event);
  138.         if (event.type == KeyPress) {
  139.             done = True;
  140.         }
  141.     }
  142. }
  143.  
  144.  
  145.  
  146. /*
  147.  * Set up the X window.
  148.  */
  149. static void
  150. x_window_setup(title, author)
  151.     char *title;
  152.     char *author;
  153. {
  154.     XSetWindowAttributes  win_attr;    /* storage for "window attributes" */
  155.     XSizeHints            hints;       /* storage for "window hints" */
  156.     XGCValues             gcval;
  157.     int                   screen;
  158.     char                  label[256];
  159.  
  160.     /*
  161.      * Open the display.
  162.      */
  163.     if (NULL == (x_display = XOpenDisplay(NULL))) {
  164.         fputs("Can't open display.\n", stderr);
  165.         exit(1);
  166.     }
  167.  
  168.     /*
  169.      * Create the window.
  170.      */
  171.     screen = DefaultScreen(x_display);
  172.     x_depth = DefaultDepth(x_display, DefaultScreen(x_display));
  173.     x_window = XCreateSimpleWindow(x_display, DefaultRootWindow(x_display),  
  174.                                    100, 100, 320, 200, 0, 
  175.                                    BlackPixel(x_display, screen), 
  176.                                    BlackPixel(x_display, screen));
  177.  
  178.     /* 
  179.      * set up "window hints" so that we won't be allowed to
  180.      * resize the window while it's running 
  181.      */
  182.     sprintf(label, "%s %s %s", title, (author[0] ? "by" : ""), author);
  183.     hints.flags = PSize | PMinSize | PMaxSize;
  184.     hints.width = hints.min_width = hints.max_width = 320;
  185.     hints.height = hints.min_height = hints.max_height = 200;
  186.     XSetStandardProperties(x_display, x_window, label, title, 
  187.                            None, NULL, 0, &hints);
  188.  
  189.     /*
  190.      * Tell the server which events we want to recieve.
  191.      * Enable backing store so we don't have to worry
  192.      * about exposes (yes I know, backing store is not
  193.      * guaranteed, but it works for me, hah).
  194.      */
  195.     win_attr.event_mask = KeyPressMask;
  196.     win_attr.backing_store = Always;
  197.     XChangeWindowAttributes(x_display, x_window, 
  198.                             CWEventMask | CWBackingStore, &win_attr);
  199.  
  200.     gcval.foreground = BlackPixel(x_display, screen);
  201.     gc_clear = XCreateGC(x_display, x_window, GCForeground, &gcval);
  202.  
  203.     XMapWindow(x_display, x_window);
  204.     XSync(x_display, False);
  205. }
  206.  
  207.  
  208. static void die(s)char*s;{fprintf(stderr,"%s\n",s);exit(1);}
  209.  
  210.  
  211. void
  212. main(argc, argv)
  213.     int        argc;
  214.     char*    argv[];
  215. {
  216.     DL_info           dlinfo;
  217.     struct itimerval  timer;
  218.     struct timeval    timeout;
  219.     char             *filename;
  220.     FILE             *fp;
  221.     u_char           *image_data;
  222.     char             *err1, *err2, *tmp;
  223.     short             alpha[256], beta[256], gamma[256], delta[256];
  224.     short             gray, err;
  225.     u_long            black, white;
  226.     int               dx, dy;
  227.     int               width, height;
  228.     int              *cmd;
  229.     int               labelpos, label;
  230.     int               cmdnum;
  231.     int               frame_freq;
  232.     int               fps = 25;
  233.     int               zoomflag = 0;
  234.     int               errflg = 0;
  235.     int               i, j;
  236.     extern char      *optarg;
  237.     extern int        optind;
  238.  
  239.  
  240.     /*
  241.      * Lets see what option we got from the user.
  242.      */
  243.     while ((i = getopt(argc, argv, "zhr:")) != -1) {
  244.     switch (i) {
  245.       case 'z':
  246.         zoomflag = 1;
  247.           break;
  248.  
  249.       case 'h':
  250.         errflg++;
  251.         break;
  252.  
  253.       case 'r':
  254.         fps = atoi(optarg);
  255.         if (fps < 2) {
  256.             printf("Minimum value is 2 frames per second.\n");
  257.             fps = 2;
  258.         }
  259.         break;
  260.  
  261.       case '?':
  262.       default:
  263.         errflg++;
  264.     }
  265.     }
  266.     if (errflg) { 
  267.         fputs("usage: xdl [-z] [-h] [-r frames/second] [file.dl]\n", stderr);
  268.     exit (2);
  269.     }
  270.     
  271.     if (argv[optind] == NULL) {
  272.         fp = stdin;
  273.         filename = "stdin";
  274.     } else if (NULL == (fp = fopen(argv[optind], "r"))) {        
  275.         fprintf(stderr, "xdl: can't open %s\n", argv[1]);
  276.         exit(1);
  277.     } else {
  278.         filename = argv[optind];
  279.     }
  280.  
  281.  
  282.     /*
  283.      * Check the version number...
  284.      */
  285.     if (1 != (dlinfo.version = fgetc(fp)) && 2 != dlinfo.version) {
  286.         fprintf(stderr, "xdl: This file is in an unknown format.\n");
  287.         fprintf(stderr, "     I can only do .DL version 1 and 2.\n", 
  288.                 dlinfo.version);
  289.         exit(1);
  290.     }
  291.     
  292.  
  293.     /*
  294.      * ...and the format.
  295.      */
  296.     if (dlinfo.version == 1)
  297.         dlinfo.format = 1;
  298.     else
  299.         dlinfo.format = fgetc(fp);
  300.     
  301.     switch (dlinfo.format) {
  302.       case 0: /* large */
  303.         dx = dy = 0;
  304.         width = 320;
  305.         height = 200;
  306.         dlinfo.images_per_screen = 1;
  307.         zoomflag = 0;
  308.         break;
  309.       case 1: /* medium */
  310.         if (zoomflag) {
  311.             dx = dy = 0;
  312.             width = 320;
  313.             height = 200;
  314.         } else {
  315.             dx = 80;
  316.             dy = 50;
  317.             width = 160;
  318.             height = 100;
  319.         }
  320.         dlinfo.images_per_screen = 4;
  321.         break;
  322.       default:
  323.         die("xdl: only large and medium formats are handled");
  324.         break;
  325.     }
  326.     
  327.  
  328.     /*
  329.      * Get title and author (if any).
  330.      */
  331.     dlinfo.title[20] = dlinfo.author[20] = 0;
  332.     for (i = 0; i < 20; i++) {
  333.         dlinfo.title[i] = fgetc(fp) ^ 255;
  334.         if ((u_char)dlinfo.title[i] == 255) {
  335.             dlinfo.title[i] = 0;
  336.